use std::sync::Arc;
use std::time::Duration;
use once_cell::sync::Lazy;
use rbatis::RBatis;
use crate::config::config::ApplicationConfig;

pub mod api_handler;
pub mod user_handler;
mod sys_trash_service;

pub static CONTEXT: Lazy<ServiceContext> = Lazy::new(|| ServiceContext::de);

pub struct ServiceContext {
    pub config: ApplicationConfig,
    pub rb: RBatis,
    pub sys_user_service: user_handler,
}

impl ServiceContext {
    pub async fn init_database(&self) {
        log::info!(
            "[abs_admin] rbatis pool init ({})...",
            self.config.db_url
        );
        self.rb
            .link(
                include!("../../target/driver.rs"),
                &self.config.db_url,
            )
            .await
            .expect("[abs_admin] rbatis pool init fail!");
        self.rb.intercepts.push(Arc::new(SysTrashService::new()));
        self.rb.get_pool().unwrap().set_max_open_conns(self.config.db_pool_len as u64).await;
        self.rb.get_pool().unwrap().set_timeout(Some(Duration::from_secs(self.config.db_pool_timeout as u64))).await;
        log::info!(
            "[abs_admin] rbatis pool init success! pool state = {}",
            self.rb.get_pool().expect("pool not init!").state().await
        );
        log::info!(
            " - Local:   http://{}",
            self.config.server_url.replace("0.0.0.0", "127.0.0.1")
        );
    }
}

impl Default for ServiceContext {
    fn default() -> Self {
        let config = ApplicationConfig::default();
        ServiceContext {
            rb: {
                let rb = RBatis::new();
                if rb.is_debug_mode() == false && config.debug.eq(&true) {
                    panic!(r#"please edit application.json5   “debug: false” "#);
                }
                rb
            },
            sys_user_service: user_handler {}
            ,
            config,
        }
    }
}